home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / NotePads / Notes / Source / Main.m < prev    next >
Encoding:
Text File  |  1992-08-04  |  7.0 KB  |  389 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "Main.h"
  5. #import <appkit/Text.h>
  6. #import <appkit/Panel.h>
  7. #import <appkit/Window.h>
  8. #import <appkit/ScrollView.h>
  9. #import <appkit/Listener.h>
  10. #import <appkit/Button.h>
  11. #import <appkit/Matrix.h>
  12. #import <appkit/Pasteboard.h>
  13. #import <streams/streams.h>
  14. #import <defaults.h>
  15. #include <sys/file.h>
  16. #include <stdio.h>
  17. #import <libc.h>
  18.  
  19. #define APPNAME "Notes"
  20.  
  21. char path[1024] = "";
  22. // The application listener.
  23. id listener;
  24.  
  25.  
  26. // Definitions for the default insertion position
  27. #define START 1
  28. #define END 0
  29. // Default insertion position.
  30. int insertPos;
  31.  
  32.  
  33. // Has the app been initialized.
  34. int init=0;
  35. // Were we autolaunched?
  36. int justauto=0;
  37. // Should we display the main window?
  38. int shouldshow;
  39. // Have we displayed the main window?
  40. int hasshown = 0;
  41.  
  42.  
  43.  
  44. @implementation Main
  45.  
  46.  
  47. /* Intercept termination to write text and defaults.*/
  48. - terminate:sender
  49. {
  50.     [self writeText];
  51.     [self writePrefs];
  52.     return [super terminate:sender];
  53. }
  54.  
  55. /* If the user logs out, we get these rather than the terminate message.*/
  56. - app:sender powerOffIn:(int)ms andSave:(int)aFlag
  57. {
  58.     [self writeText];
  59.     return self;
  60. }
  61. - powerOff:(NXEvent *)theEvent
  62. {
  63.     [self writeText];
  64.     return self;
  65. }
  66.  
  67.  
  68.  
  69. /* Set self as the services handler.*/
  70. - appDidInit:sender
  71. {
  72.     listener = [NXApp appListener];
  73.     [listener setServicesDelegate:self];
  74.     return self;
  75. }
  76.  
  77. /* Actual initialization, is called every time the application activates.*/
  78. - doinit
  79. {
  80.     /* Perform initialization only if this is the first time.*/
  81.     if (init==0)
  82.     {
  83.         /* Register defaults.*/
  84.         static NXDefaultsVector Defaults = {
  85.             {"InsertPosition", "START"},
  86.             {"WindowFrame", "360 350 500 250"},
  87.             {"NXAutoLaunch", "NO"},
  88.             {NULL}
  89.             };
  90.         NXRegisterDefaults(APPNAME, Defaults);
  91.         /* Get the defaults and the text.*/
  92.         [self readPrefs];
  93.         [self readText];
  94.         /*
  95.             Decide if we should display the window.
  96.             We don't show if and only if the app has just been autolaunched and the
  97.             text is empty.
  98.         */
  99.         shouldshow = !(justauto && ([self textlength]==0));
  100.         init++;
  101.     }
  102.     return self;
  103. }
  104.  
  105.  
  106.  
  107.  
  108. /* The number of characters in the text.*/
  109. - (int)textlength
  110. {
  111.     return [text textLength];
  112. }
  113.  
  114.  
  115. - (int)activateSelf:(BOOL)flag
  116. {
  117.     /* Make sure initialization has been performed.*/
  118.     [self doinit];
  119.     /*
  120.         If we're supposed to display the window, and haven't yet done so, then
  121.         display it.
  122.     */
  123.     if (shouldshow)
  124.         if (!hasshown)
  125.         {
  126.             [window makeKeyAndOrderFront:self];
  127.             hasshown = !hasshown;
  128.         }
  129.     /*
  130.         From now on, we should always bring the window to the front when 
  131.         activated.
  132.     */
  133.     shouldshow = 1;
  134.     return [super activateSelf:flag];
  135. }
  136.  
  137.  
  138.  
  139.  
  140. /* From the menu.*/
  141.  
  142. - quitNoSave:sender
  143. {
  144.     int ok;
  145.     /* If the text has been editted, ask for confirmation, otherwise go ahead.*/
  146.     if ([window isDocEdited])
  147.         ok = NXRunAlertPanel(APPNAME, "Quit without saving text?", "Quit", "Cancel", NULL)==NX_ALERTDEFAULT;
  148.     else
  149.         ok = 1;
  150.     if (ok) [super terminate:sender];
  151.     return self;
  152. }
  153.  
  154. - save:sender
  155. {
  156.     [self writeText];
  157.     [text becomeFirstResponder];
  158.     [text setSel:0:0];
  159.     return self;
  160. }
  161.  
  162. - reload:sender
  163. {
  164.     int ok;
  165.     /* If the text has been edited, confirm reload, otherwise go ahead.*/
  166.     if ([window isDocEdited])
  167.         ok = NXRunAlertPanel(APPNAME, "Reload text?\nAny changes will be lost.", "Reload", "Cancel", NULL)==NX_ALERTDEFAULT;
  168.     else
  169.         ok = 1;
  170.     if (ok) [self readText];
  171.     return self;
  172. }
  173.  
  174. - print:sender
  175. {
  176.     [text printPSCode:sender];
  177.     return self;
  178. }
  179.  
  180.  
  181.  
  182.  
  183.  
  184. /* Buttons on the prefs panel.*/
  185. - okPrefs:sender
  186. {
  187.     [self takePrefsFromInterface];
  188.     [NXApp stopModal];
  189.     [prefsPanel orderOut:self];
  190.     return self;
  191. }
  192.  
  193. - revertPrefs:sender
  194. {
  195.     [self setPrefsInterface];
  196.     return self;
  197. }
  198.  
  199. - cancelPrefs:sender
  200. {
  201.     [NXApp stopModal];
  202.     [prefsPanel orderOut:self];
  203.     return self;
  204. }
  205.  
  206. /* Display the prefs panel.*/
  207. - showPrefs:sender
  208. {
  209.     [self setPrefsInterface];
  210.     [NXApp runModalFor:prefsPanel];
  211.     return self;
  212. }
  213.  
  214. /* Set up the prefs panel according to the current values of the defaults.*/
  215. - setPrefsInterface
  216. {
  217.     [enabledSwitch setState:NXIsServicesMenuItemEnabled("Note") ? 1 : 0];
  218.     [positions selectCellAt:insertPos:0];
  219.     return self;
  220. }
  221.  
  222. /* Set the new values of the defaults according to the prefs panel.*/
  223. - takePrefsFromInterface
  224. {
  225.     NXSetServicesMenuItemEnabled("Note",[enabledSwitch state]);
  226.     if ([startSwitch state])
  227.         insertPos = START;
  228.     else
  229.         insertPos = END;
  230.     return self;
  231. }
  232.  
  233.  
  234.  
  235.  
  236. /* Get the defaults.*/
  237. - readPrefs
  238. {
  239.     char    const *def;
  240.     int x,y,h,w;
  241.     NXRect frame;
  242.  
  243.     /* Location of the text window.*/
  244.     def = NXGetDefaultValue(APPNAME, "WindowFrame");
  245.     sscanf(def, "%i %i %i %i", &x, &y, &w, &h);
  246.     /* Position the window.*/
  247.     frame = (NXRect){{x,y},{w,h}};
  248.     [window placeWindow:&frame];
  249.     
  250.     /* Insertion position.*/
  251.     def = NXGetDefaultValue(APPNAME, "InsertPosition");
  252.     if (strcmp(def, "START")==0)
  253.         insertPos = START;
  254.     else
  255.         insertPos = END;
  256.         
  257.     /* Were we autolaunched?.*/
  258.     def = NXGetDefaultValue(APPNAME, "NXAutoLaunch");
  259.     justauto = strcmp(def, "YES")==0;
  260.     
  261.     return self;
  262. }
  263.  
  264. /* Read the text from the file in the user's home dir.*/
  265. - readText
  266. {
  267.     int    fd;
  268.     NXStream *st;
  269.     
  270.     // Find the file in the user's home directory.
  271.     sprintf(path, "%s/.Notes", getenv("HOME"));
  272.  
  273.     fd = open(path, O_RDONLY, 0);
  274.     if (fd >= 0)
  275.     {
  276.         if ((st = NXOpenFile(fd, NX_READONLY)) != 0)
  277.         {
  278.             [text readRichText:st];
  279.             [text sizeToFit];
  280.             NXClose(st);
  281.         }
  282.         close(fd);
  283.     }
  284.     
  285.     /* Adjust interface.*/
  286.     [window setDocEdited:NO];
  287.     [text becomeFirstResponder];
  288.     [text setSel:0:0];
  289.     return self;
  290. }
  291.  
  292. /* Store the defaults.*/
  293. - writePrefs
  294. {
  295.     int x,y,h,w;
  296.     NXRect    frame;
  297.     char def[100];
  298.     
  299.     NXWriteDefault(APPNAME, "InsertPosition",(insertPos==START)?"START":"END");
  300.     [window getFrame:&frame];
  301.     x = frame.origin.x;
  302.     y = frame.origin.y;
  303.     w = frame.size.width;
  304.     h = frame.size.height;
  305.     sprintf(def, "%i %i %i %i", x,y,w,h);
  306.     NXWriteDefault(APPNAME, "WindowFrame", def);
  307.     return self;
  308. }
  309.  
  310. /* Write the text into the file in the user's home directory.*/
  311. - writeText
  312. {
  313.     int    fd;
  314.     NXStream    *st;
  315.     
  316.     fd = open(path, O_WRONLY | O_CREAT, 0xfff);
  317.     if (fd >= 0)
  318.     {
  319.         if ((st = NXOpenFile(fd, NX_WRITEONLY)) != 0)
  320.         {
  321.             [text writeRichText:st];
  322.             NXClose(st);
  323.         }
  324.         close(fd);
  325.     }
  326.     [window setDocEdited:NO];
  327.     return self;
  328. }
  329.  
  330.  
  331.  
  332.  
  333. /* Handle the note service.*/
  334. - note:(id)pb userData:(const char *)udata error:(char **)ermsg
  335. {
  336.     int tlength;
  337.     NXSelPt start,end;
  338.  
  339.     /* Determine if there is a selection in the text window.*/
  340.     [text getSel:&start:&end];
  341.  
  342.     /* If there isn't, so set a selection according to preference.*/
  343.     if (start.cp==end.cp || start.cp < 0)
  344.     {
  345.         if (insertPos==START)
  346.         {
  347.             [text setSel:0:0];
  348.             [text replaceSel:"\n"];
  349.             [text setSel:0:0];
  350.         }
  351.         else
  352.         {
  353.             tlength = [text textLength];
  354.             [text setSel:tlength:tlength];
  355.             [text replaceSel:"\n"];
  356.             [text setSel:tlength+1:tlength+1];
  357.         }
  358.     }
  359.     
  360.     /* Now replace the selection with the pasteboard data.*/
  361.     [text readSelectionFromPasteboard:pb];
  362.     return self;
  363. }
  364.  
  365.  
  366.  
  367.  
  368. /* Set the close button to edited state.*/
  369. - (BOOL)textWillChange:sender
  370. {
  371.     [window setDocEdited:YES];
  372.     return NO;
  373. }
  374.  
  375.  
  376. /*
  377. Intercept the outlet initialization to find the text object that is the subview of the scolling text, adn set us self as the text's delegate.
  378. */
  379. - setScroll:anObject
  380. {
  381.     scroll = anObject;
  382.     text = [scroll docView];
  383.     [text setDelegate:self];
  384.     [self setDelegate:self];
  385.     return self;
  386. }
  387.  
  388. @end
  389.